# python 赋值原理
# 变量并不直接存储对象的值, 而是存储对象的引用 (即对象在内存中的地址)

# 对于不可变数据类型: 数字, 布尔, 字符串, 元组
# a = 1
# b = a
# print("a绑定的内存地址为: ", id(a))
# print("b绑定的内存地址为: ", id(b))

# 对于可变数据类型: 列表, 集合, 字典
# l1 = [1, 2, 3]
# l2 = l1
# print("l1绑定的内存地址为: ", id(l1))
# print("l2绑定的内存地址为: ", id(l2))
# l1[0] = 4
# print(l1)
# print(l2)

# 将一个变量赋值给另一个变量时, 复制的是对象的"引用", 二者实际上指向了同一个对象
# 问题: 这意味着如果修改对象的值, 两者都会受到影响
# 为了避免变量之间共享地址带来的问题, 就有了浅拷贝和深拷贝, 需要复制对象的"值"

# 浅拷贝
# import copy

# 对于不可变数据类型, 复制"引用"
# a = 1
# b = copy.copy(a)
# print("a绑定的内存地址为: ", id(a))
# print("b绑定的内存地址为: ", id(b))

# 对于可变数据类型,复制"值"
# l1 = [1, 2, 3]
# l2 = copy.copy(l1)
# print("l1绑定的内存地址为: ", id(l1))
# print("l2绑定的内存地址为: ", id(l2))
# l1[0] = 4
# print(l1)
# print(l2)

# 对于较复杂的数据, 可变数据类型在内外层时表现不同
# l3 = [1, [2, 3]]
# l4 = copy.copy(l3)
# l3[0] = 4
# l3[1][0] = 3
# print(l3)
# print(l4)

# 浅拷贝对不可变数据类型, 复制"引用"
# 浅拷贝对可变数据类型
    # 可变数据类型在外层时, 复制"值"
    # 可变数据类型在内层时, 复制"引用"

# 深拷贝
import copy

l3 = [1, [2, 3]]
l4 = copy.deepcopy(l3)
print(id(l3))
print(id(l4))
print(id(l3[1]))
print(id(l4[1]))

# 深拷贝对不可变数据类型, 复制"引用", 对可变数据类型, 复制"值"

'''
面试题
浅拷贝和深拷贝的区别?[3]
- 浅拷贝和深拷贝的出现源于变量赋值只赋予变量对数据对象的引用, 当多个变量引用同一
数据时, 数据一旦修改, 这些变量都会受影响
- 浅拷贝和深拷贝在实现上都用到了copy模块, 浅拷贝用的copy()函数, 深拷贝用的是deepcopy()函数
- 对于不可变类型的数据处理, 浅拷贝和深拷贝是一样的, 都是复制对数据的"引用", 并不会开辟新的内存地址
- 对于可变类型的数据处理
    - 浅拷贝的处理方式是, 外层的数据复制"值", 内层的数据复制"引用"
    - 深拷贝的处理方式是, 不论内外层都开辟新的内存地址, 都复制"值"
'''